package update_history_editor_material_audit_data

import (
	"cid-media-api/global"
	"cid-media-api/models"
	syncCmd "cid-media-api/workers/data/sync-editor-material-audit-data"
	"fmt"
	"github.com/robfig/cron/v3"
	"github.com/samber/lo"
	"log"
	"os"
	"sync"
	"time"
)

func updateHistoryMaterialAuditData(date string, logger *log.Logger) {
	logger.Printf("开始更新日期: %s 的历史剪辑素材审核信息", date)
	groupIds := []int{
		1028,
		// 1029,
		// 1034,
		// 1036
	} // 事业部门

	for _, groupId := range groupIds {
		// 获取今日的素材报表数据

		var materialReportData []models.CmsReportDayMaterial

		global.SucaiDb.
			Model(models.CmsReportDayMaterial{}).
			Where("cms_group_id =? AND tdate =?", groupId, date).
			Find(&materialReportData)

		materialIds := lo.Uniq(lo.Map(materialReportData, func(item models.CmsReportDayMaterial, index int) string {
			return item.MaterialID
		}))

		var historyFiles []models.File

		global.SucaiDb.
			Model(models.File{}).
			Joins("left join file_push_tasks on file_push_tasks.file_id = files.id").
			Where("material_id in (?)", materialIds).
			Where("file_push_tasks.status =?", 1).
			Select([]string{"files.id", "files.name", "files.created_at_date", "files.is_fission", "files.fission_pid",
				"files.clone_id", "files.video_editor"}).
			Find(&historyFiles)

		originData := lo.Filter(historyFiles, func(item models.File, index int) bool {
			return item.IsFission == 0 && item.CloneID == 0
		})
		originIds := lo.Uniq(lo.Map(originData, func(item models.File, index int) int {
			return item.ID
		}))

		cloneData := lo.Filter(historyFiles, func(item models.File, index int) bool {
			return item.IsFission == 0 && item.CloneID > 0
		})
		cloneOriginIds := lo.Uniq(lo.Map(cloneData, func(item models.File, index int) int {
			return item.CloneID
		}))

		fissionData := lo.Filter(historyFiles, func(item models.File, index int) bool {
			return item.IsFission == 1
		})
		fissionOriginIds := lo.Uniq(lo.Map(fissionData, func(item models.File, index int) int {
			return item.FissionPid
		}))

		allOriginIds := lo.Uniq(append(originIds, append(cloneOriginIds, fissionOriginIds...)...))

		var allOriginFiles []models.File

		global.SucaiDb.
			Model(models.File{}).
			Where("id in (?)", allOriginIds).
			Find(&allOriginFiles)

		logger.Printf("获取到 %d 条历史剪辑素材数据\n", len(allOriginFiles))

		originFilesByDate := lo.GroupBy(allOriginFiles, func(item models.File) string {
			return lo.Substring(item.CreatedAtDate, 0, 10)
		})

		// 按日期遍历分组
		for createDate, originFiles := range originFilesByDate {
			logger.Println("当前日期：", createDate)

			editorIds := lo.Uniq(lo.Map(originFiles, func(item models.File, index int) int {
				return item.VideoEditor
			}))

			var editors []models.CmsUser

			global.SucaiDb.
				Model(models.CmsUser{}).
				Where("id in (?)", editorIds).
				Find(&editors)

			editorCidUIds := lo.Map(editors, func(item models.CmsUser, index int) int {
				return item.UID
			})

			type sysUser struct {
				UID    int `json:"uid"`
				TeamID int `json:"team_id"`
			}

			var editorUsers []sysUser

			global.CidDb.
				Table("sys_users").
				Where("uid in (?)", editorCidUIds).
				Select([]string{"uid, team_id"}).
				Find(&editorUsers)

			// 如果临时表已经存在，则删除
			if global.SucaiDb.Migrator().HasTable(&models.EditorMaterialAuditDataTempUpdateHistory{}) {
				err := global.SucaiDb.Migrator().DropTable(&models.EditorMaterialAuditDataTempUpdateHistory{})
				if err != nil {
					logger.Printf("删除已经存在的临时表失败: %s\n", err)
				}
			}

			// 创建临时表
			err := global.SucaiDb.Migrator().CreateTable(&models.EditorMaterialAuditDataTempUpdateHistory{})
			if err != nil {
				logger.Printf("创建临时表失败: %s\n", err)
			}

			wg := sync.WaitGroup{}

			// 按剪辑人员获取
			for _, editor := range editors {
				wg.Add(1)
				go func(editor models.CmsUser) {
					defer wg.Done()
					editorUser, _ := lo.Find(editorUsers, func(user sysUser) bool {
						return user.UID == editor.UID
					})
					editor.TeamID = editorUser.TeamID

					logger.Printf("开始更新部门 %d 的剪辑人员 %s (ID: %d) 的素材审核信息\n", editor.GroupID, editor.RealName, editor.ID)
					syncCmd.GetMaterialAuditDataByEditor(createDate, editor, "UPDATE_HISTORY")
					logger.Printf("更新部门 %d 的剪辑人员 %s (ID: %d) 的素材审核信息完成\n", editor.GroupID, editor.RealName, editor.ID)
				}(editor)
			}

			wg.Wait()

			// 将临时表中的新数据更新至原表中
			logger.Printf("正在从临时表向原表更新 %s 的历史剪辑审核统计报表数据...\n", createDate)
			global.SucaiDb.Exec(
				fmt.Sprintf(
					"INSERT INTO %s (`key`, editor_id, editor_name, group_id, team_id, file_create_date, file_id, file_name, "+
						"				file_date_prefix, audit_status_init_origin, "+
						"               audit_status, cost, gmv, roi, push_status, audit_success_count, derive_from, "+
						"               derived_file_count, derive_type, report_data,audit_status_origin, click, "+
						"               `show`, `convert`, valid_play, total_play, created_at, updated_at) "+
						"SELECT `key`, editor_id, editor_name, group_id, team_id, file_create_date, file_id, file_name, "+
						"	   file_date_prefix, audit_status_init_origin, "+
						"      audit_status, cost, gmv, roi, push_status, audit_success_count, derive_from, "+
						"      derived_file_count, derive_type, report_data, audit_status_origin, click, "+
						"      `show`, `convert`, valid_play, total_play, created_at, updated_at "+
						"FROM %s "+
						"ON DUPLICATE KEY UPDATE "+
						"	`key` = VALUES(`key`), "+
						"	editor_id = VALUES(editor_id), "+
						"	editor_name = VALUES(editor_name), "+
						"	group_id = VALUES(group_id), "+
						"	team_id = VALUES(team_id), "+
						"	file_create_date = VALUES(file_create_date), "+
						"	file_name = VALUES(file_name), "+
						"	audit_status = VALUES(audit_status), "+
						"	cost = VALUES(cost), "+
						"	gmv = VALUES(gmv), "+
						"	roi = VALUES(roi), "+
						"	push_status = VALUES(push_status), "+
						"	audit_success_count = VALUES(audit_success_count), "+
						"	derived_file_count = VALUES(derived_file_count), "+
						"	derive_type = VALUES(derive_type), "+
						"	report_data = VALUES(report_data), "+
						"	audit_status_origin = VALUES(audit_status_origin), "+
						"	click = VALUES(click), "+
						"	`convert` = VALUES(`convert`), "+
						"	`show` = VALUES(`show`), "+
						"	valid_play = VALUES(valid_play), "+
						"	total_play = VALUES(total_play), "+
						"	created_at = VALUES(created_at), "+
						"	updated_at = VALUES(updated_at)",
					(&models.EditorMaterialAuditData{}).TableName(), (&models.EditorMaterialAuditDataTempUpdateHistory{}).TableName()))

			err = global.SucaiDb.Migrator().DropTable(&models.EditorMaterialAuditDataTempUpdateHistory{})
			if err != nil {
				logger.Printf("删除临时表失败: %s\n", err)
			}
		}
	}
}

func Execute(date string, logger *log.Logger) {
	logger.Println("开始更新历史剪辑素材审核信息")
	logger.Printf("开始时间：%s\n", time.Now().Format(time.DateTime))

	updateHistoryMaterialAuditData(date, logger)

	logger.Printf("结束时间：%s\n", time.Now().Format(time.DateTime))
	logger.Println("素材审核统计历史信息更新完成")
}

func Run(cronSpec string) {
	c := cron.New()
	c.AddFunc(cronSpec, func() {
		logFile, err := os.OpenFile("/www/logs/cid-media-api/crontab/update_history_material_audit_data_"+time.Now().Format(time.DateOnly)+".log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			log.Fatal(err)
		}
		defer logFile.Close()

		logger := log.New(logFile, "", log.LstdFlags)
		// 更新脚本默认跑11-14到6天前的数据
		endDate := time.Now().AddDate(0, 0, -5).Format(time.DateOnly)
		startDate := "2024-11-14"
		syncCmd.Execute(startDate, endDate, logger)
	})

	c.Run()
}
